# -*- coding: utf-8 -*-

"""
Created on Fri Jun  8 18:43:24 2018

@author: Administrator
"""
#%%
import sys
import os
import glob
import shutil

from ..origin import Shell_script
from ..log import Log_make
from ..distribute import MultiThread
#----------------------------------------------以下内容为错误信息log记录
#主函数要求：import sys
#主函数要求： if not os.path.exists(medi): os.makedirs(medi) f.write(）要求medi指定的文件夹必须存在，
#主函数要求：err_log_path = medi + os.sep + sys._getframe().f_code.co_name + '_err_log.txt'
#主函数要求：err_log_write(log_path,item,stdout_err,i,j)
#主函数要求：其中medi应该根据情况重新定义
#主函数要求：此处共定义了2个err_log_write，不能同时使用。第一个是通用情况，第二个主要是针对subprocess模块的。
#主函数要求：每一个出错的部位都设一个i = i + 1
class File_convert_copy(Shell_script):
    #作用原理：如果传入的in_file_path是nii.gz的文件，则直接复制。如果不是nii.gz的文件，则用mri_convert转换成nii.gz的格式。
    #参数说明：input_list必须有且仅有2个参数。第一个参数为源文件的fullpath，第二参数为target dir path。
    #返回值说明：stdout_err是popen_subj的执行情况的返回结果。
    #举例：
    #调用：
    #被调用：prepare_for_analysis()
    #bug：
    
    def __init__(self,input_list=[]):
        self.initialize_input_list(input_list)
        self.concat_inputs()
        self.concat_script()
        if os.path.exists(self.out_file_path):
            #if the file is already exist,then there is no neeed to convert or copy the file.s
            self.stdout_err = [b'',b'']
        if self.suffix in self.in_file_path:
            #if the file which the variable 'in_file_path' pointed to is not in nii.gz format,then 
            #it should be converted to nii.gz by the shell command mri_convert
            shutil.copy2(self.in_file_path,self.easy_analysis_path)
        else:
            self.excute_shell_script()
    
    def initialize_input_list(self,input_list):
        if len(input_list) != 3:
            raise Exception("incompatible parameter amount ") 
        self.in_file_path = input_list[0]
        self.easy_analysis_path = input_list[1]
        self.suffix = input_list[2]
        
    def concat_inputs(self):
        self.out_file_path = self.easy_analysis_path + self.os_sep + os.path.split(self.in_file_path)[1].split('.')[0] + self.suffix
        
    def concat_script(self):
        ###########################################################################构造命令、即脚本执行。
        #mri_convert -it nii -ot nii  /download/img.nii    /documents/img.nii.gz
        cmd_3 = r' mri_convert -it nii ' + self.in_file_path + self.space + self.out_file_path
        self.shell_script = cmd_3
#%%
        
class Regular2processing(MultiThread,Log_make):
    #作用原理：将经典的文件结构（详见dir_layout.pptx），转换成可以被agile批处理的文件结构，可以接受.nii或.nii.gz文件，但输出一定是.nii.gz文件。
    #作用原理：凡是已经成功复制或者转换了的文件不用再重复复制、或者转换。当半路程序终端后，可以找到相应的文件夹，然后把复制到一般的文件删去，然后再
    #作用原理：重新开始即可。
    #参数说明：classical_path=r'/media/root/Elements/XuanWu_gz/regular'，此文件夹内就是subj_1等命名的文件夹。在往下就是T1、PET、ASL命名的文件夹。
    #参数说明：modality_list必须是['T1','PET','ASL','CBF','BOLD']
    #参数说明：core_percent是指用百分之多少的核心进行并行处理。
    #返回值说明：
    #举例：
    #调用：file_convert_copy
    #被调用：暂无
    #bug：    
    
    pckg =  ' agilepipe.organize '
    key = 'File_convert_copy'  #file_convert_copy用于复制及转换img格式的类
    def __init__(self,classical_path,modality_list,suffix,core_percent):
        medi = os.path.split(classical_path)[0]
        #preparing essential parameters
        if not os.path.exists(medi): 
            os.makedirs(medi)
        asterisk = r'*'
        for item in modality_list:
            file_path_list = glob.glob(classical_path+(os.sep+asterisk)*3+item+asterisk)
            #print(file_path_list)
            easy_analysis_path = os.path.split(classical_path)[0] + os.sep + item
            if not os.path.exists(easy_analysis_path):
                os.makedirs(easy_analysis_path)
    
            #下面为pool.map构建parameter_list,parameter_list must be initialized every 'for cycle',because the trait of append method of list.
            parameter_list = []    
            for in_file_path in file_path_list: 
                parameter_list.append([in_file_path,easy_analysis_path,suffix])
                
            process_result_list = self.parallel(self.key,parameter_list,core_percent)
            
            #下面的代码是根据self.parallel返回的结果进行日志记录
            i = 0
            for process_obj in process_result_list:
                if process_obj.stdout_err != None:
                    #之所以这样判断是因为afni下面的如3dcalc等命令的stdout stderr非常特殊。详见key值指向的函数。
                    print('errorerrorerrorerrorerrorerrorerror')
                    print('stdout_err:',process_obj)
                    print('i:',i)
                    if not os.path.exists(item):
                        os.makedirs(item)
                    err_log_path = medi + os.sep + sys._getframe().f_code.co_name + '_err_log.txt'
                    self.shell_err_log_write(err_log_path,item,process_obj.stdout_err,file_path_list[i],i)
                    #previous_filename,present_filename这两个参数是不对的。
                    i = i + 1

#%%
if __name__ == '__main__':
    #由于相对导入的问题，如from ..distribute import MultiThread，本部分运行会有问题，因此仅供参考。
    classical_path = r'/media/root/Elements/XuanWu_gz/regular'
    modality_list = ['T1','PET','ASL','CBF','BOLD']
    #the order of elements of the modality_list is same to the order of the converting and copying
    suffix = '.nii.gz'  # suffix = '.nii' 
    core_percent = 0.7
    Regular2processing(classical_path,modality_list,suffix,core_percent)
